{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[DEBUG@graphviz.backend.execute] run [WindowsPath('dot'), '-V']\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "('0.19', (2, 49, 3))"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "%cd -q ..\n",
    "\n",
    "import logging\n",
    "\n",
    "import graphviz\n",
    "\n",
    "logging.basicConfig(format='[%(levelname)s@%(name)s] %(message)s', level=logging.DEBUG)\n",
    "\n",
    "graphviz.__version__, graphviz.version()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[DEBUG@graphviz.backend.execute] run [WindowsPath('dot'), '-Kdot', '-Tsvg']\n"
     ]
    },
    {
     "data": {
      "image/svg+xml": [
       "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
       "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
       " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
       "<!-- Generated by graphviz version 2.49.3 (20211023.0002)\n",
       " -->\n",
       "<!-- Pages: 1 -->\n",
       "<svg width=\"390pt\" height=\"116pt\"\n",
       " viewBox=\"0.00 0.00 389.98 116.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
       "<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 112)\">\n",
       "<polygon fill=\"white\" stroke=\"transparent\" points=\"-4,4 -4,-112 385.98,-112 385.98,4 -4,4\"/>\n",
       "<!-- A -->\n",
       "<g id=\"node1\" class=\"node\">\n",
       "<title>A</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"190.99\" cy=\"-90\" rx=\"53.89\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"190.99\" y=\"-86.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">King Arthur</text>\n",
       "</g>\n",
       "<!-- B -->\n",
       "<g id=\"node2\" class=\"node\">\n",
       "<title>B</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"90.99\" cy=\"-18\" rx=\"90.98\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"90.99\" y=\"-14.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">Sir Bedevere the Wise</text>\n",
       "</g>\n",
       "<!-- A&#45;&gt;B -->\n",
       "<g id=\"edge1\" class=\"edge\">\n",
       "<title>A&#45;&gt;B</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M168.8,-73.46C155.33,-64.04 137.92,-51.85 122.98,-41.39\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"124.72,-38.33 114.52,-35.47 120.7,-44.07 124.72,-38.33\"/>\n",
       "</g>\n",
       "<!-- L -->\n",
       "<g id=\"node3\" class=\"node\">\n",
       "<title>L</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"290.99\" cy=\"-18\" rx=\"90.98\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"290.99\" y=\"-14.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">Sir Lancelot the Brave</text>\n",
       "</g>\n",
       "<!-- A&#45;&gt;L -->\n",
       "<g id=\"edge2\" class=\"edge\">\n",
       "<title>A&#45;&gt;L</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M213.19,-73.46C226.65,-64.04 244.07,-51.85 259.01,-41.39\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"261.28,-44.07 267.47,-35.47 257.27,-38.33 261.28,-44.07\"/>\n",
       "</g>\n",
       "<!-- B&#45;&gt;L -->\n",
       "<g id=\"edge3\" class=\"edge\">\n",
       "<title>B&#45;&gt;L</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M182.01,-18C184.62,-18 187.22,-18 189.83,-18\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"189.89,-21.5 199.89,-18 189.89,-14.5 189.89,-21.5\"/>\n",
       "</g>\n",
       "</g>\n",
       "</svg>\n"
      ],
      "text/plain": [
       "<graphviz.graphs.Digraph at 0x203f26fb670>"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dot = graphviz.Digraph(comment='The Round Table')\n",
    "\n",
    "dot.node('A', 'King Arthur')\n",
    "dot.node('B', 'Sir Bedevere the Wise')\n",
    "dot.node('L', 'Sir Lancelot the Brave')\n",
    "\n",
    "dot.edges(['AB', 'AL'])\n",
    "dot.edge('B', 'L', constraint='false')\n",
    "\n",
    "dot"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[DEBUG@graphviz.backend.execute] run [WindowsPath('dot'), '-Kdot', '-Tsvg']\n"
     ]
    },
    {
     "data": {
      "image/svg+xml": [
       "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
       "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
       " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
       "<!-- Generated by graphviz version 2.49.3 (20211023.0002)\n",
       " -->\n",
       "<!-- Title: the holy hand grenade Pages: 1 -->\n",
       "<svg width=\"332pt\" height=\"44pt\"\n",
       " viewBox=\"0.00 0.00 332.00 44.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
       "<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 40)\">\n",
       "<title>the holy hand grenade</title>\n",
       "<polygon fill=\"white\" stroke=\"transparent\" points=\"-4,4 -4,-40 328,-40 328,4 -4,4\"/>\n",
       "<!-- 1 -->\n",
       "<g id=\"node1\" class=\"node\">\n",
       "<title>1</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"27\" cy=\"-18\" rx=\"27\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"27\" y=\"-14.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">1</text>\n",
       "</g>\n",
       "<!-- 2 -->\n",
       "<g id=\"node2\" class=\"node\">\n",
       "<title>2</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"117\" cy=\"-18\" rx=\"27\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"117\" y=\"-14.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">2</text>\n",
       "</g>\n",
       "<!-- 1&#45;&gt;2 -->\n",
       "<g id=\"edge1\" class=\"edge\">\n",
       "<title>1&#45;&gt;2</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M54.4,-18C62.39,-18 71.31,-18 79.82,-18\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"79.92,-21.5 89.92,-18 79.92,-14.5 79.92,-21.5\"/>\n",
       "</g>\n",
       "<!-- 3 -->\n",
       "<g id=\"node3\" class=\"node\">\n",
       "<title>3</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"207\" cy=\"-18\" rx=\"27\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"207\" y=\"-14.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">3</text>\n",
       "</g>\n",
       "<!-- 2&#45;&gt;3 -->\n",
       "<g id=\"edge2\" class=\"edge\">\n",
       "<title>2&#45;&gt;3</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M144.4,-18C152.39,-18 161.31,-18 169.82,-18\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"169.92,-21.5 179.92,-18 169.92,-14.5 169.92,-21.5\"/>\n",
       "</g>\n",
       "<!-- lob -->\n",
       "<g id=\"node4\" class=\"node\">\n",
       "<title>lob</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"297\" cy=\"-18\" rx=\"27\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"297\" y=\"-14.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">lob</text>\n",
       "</g>\n",
       "<!-- 3&#45;&gt;lob -->\n",
       "<g id=\"edge3\" class=\"edge\">\n",
       "<title>3&#45;&gt;lob</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M234.4,-18C242.39,-18 251.31,-18 259.82,-18\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"259.92,-21.5 269.92,-18 259.92,-14.5 259.92,-21.5\"/>\n",
       "</g>\n",
       "</g>\n",
       "</svg>\n"
      ],
      "text/plain": [
       "<graphviz.sources.Source at 0x203f26fa8c0>"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "src = graphviz.Source('digraph \"the holy hand grenade\" { rankdir=LR; 1 -> 2 -> 3 -> lob }')\n",
    "src"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[DEBUG@graphviz.backend.execute] run [WindowsPath('dot'), '-Kdot', '-Tsvg']\n"
     ]
    },
    {
     "data": {
      "image/svg+xml": [
       "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
       "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
       " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
       "<!-- Generated by graphviz version 2.49.3 (20211023.0002)\n",
       " -->\n",
       "<!-- Title: finite_state_machine Pages: 1 -->\n",
       "<svg width=\"576pt\" height=\"258pt\"\n",
       " viewBox=\"0.00 0.00 576.00 258.45\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
       "<g id=\"graph0\" class=\"graph\" transform=\"scale(0.77 0.77) rotate(0) translate(4 331.69)\">\n",
       "<title>finite_state_machine</title>\n",
       "<polygon fill=\"white\" stroke=\"transparent\" points=\"-4,4 -4,-331.69 744.17,-331.69 744.17,4 -4,4\"/>\n",
       "<!-- LR_0 -->\n",
       "<g id=\"node1\" class=\"node\">\n",
       "<title>LR_0</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"35.85\" cy=\"-83.85\" rx=\"31.71\" ry=\"31.71\"/>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"35.85\" cy=\"-83.85\" rx=\"35.69\" ry=\"35.69\"/>\n",
       "<text text-anchor=\"middle\" x=\"35.85\" y=\"-80.15\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">LR_0</text>\n",
       "</g>\n",
       "<!-- LR_2 -->\n",
       "<g id=\"node5\" class=\"node\">\n",
       "<title>LR_2</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"174.54\" cy=\"-151.85\" rx=\"31.7\" ry=\"31.7\"/>\n",
       "<text text-anchor=\"middle\" x=\"174.54\" y=\"-148.15\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">LR_2</text>\n",
       "</g>\n",
       "<!-- LR_0&#45;&gt;LR_2 -->\n",
       "<g id=\"edge1\" class=\"edge\">\n",
       "<title>LR_0&#45;&gt;LR_2</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M68.21,-99.45C88.53,-109.56 115.1,-122.77 136.47,-133.4\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"135.06,-136.61 145.58,-137.94 138.18,-130.35 135.06,-136.61\"/>\n",
       "<text text-anchor=\"middle\" x=\"107.19\" y=\"-129.65\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">SS(B)</text>\n",
       "</g>\n",
       "<!-- LR_1 -->\n",
       "<g id=\"node6\" class=\"node\">\n",
       "<title>LR_1</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"174.54\" cy=\"-42.85\" rx=\"31.7\" ry=\"31.7\"/>\n",
       "<text text-anchor=\"middle\" x=\"174.54\" y=\"-39.15\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">LR_1</text>\n",
       "</g>\n",
       "<!-- LR_0&#45;&gt;LR_1 -->\n",
       "<g id=\"edge2\" class=\"edge\">\n",
       "<title>LR_0&#45;&gt;LR_1</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M70.29,-73.82C89.49,-68.06 113.72,-60.79 133.88,-54.74\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"135.13,-58.02 143.7,-51.8 133.12,-51.32 135.13,-58.02\"/>\n",
       "<text text-anchor=\"middle\" x=\"107.19\" y=\"-71.65\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">SS(S)</text>\n",
       "</g>\n",
       "<!-- LR_3 -->\n",
       "<g id=\"node2\" class=\"node\">\n",
       "<title>LR_3</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"323.24\" cy=\"-35.85\" rx=\"31.71\" ry=\"31.71\"/>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"323.24\" cy=\"-35.85\" rx=\"35.69\" ry=\"35.69\"/>\n",
       "<text text-anchor=\"middle\" x=\"323.24\" y=\"-32.15\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">LR_3</text>\n",
       "</g>\n",
       "<!-- LR_4 -->\n",
       "<g id=\"node3\" class=\"node\">\n",
       "<title>LR_4</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"323.24\" cy=\"-291.85\" rx=\"31.71\" ry=\"31.71\"/>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"323.24\" cy=\"-291.85\" rx=\"35.69\" ry=\"35.69\"/>\n",
       "<text text-anchor=\"middle\" x=\"323.24\" y=\"-288.15\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">LR_4</text>\n",
       "</g>\n",
       "<!-- LR_8 -->\n",
       "<g id=\"node4\" class=\"node\">\n",
       "<title>LR_8</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"704.32\" cy=\"-152.85\" rx=\"31.71\" ry=\"31.71\"/>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"704.32\" cy=\"-152.85\" rx=\"35.69\" ry=\"35.69\"/>\n",
       "<text text-anchor=\"middle\" x=\"704.32\" y=\"-149.15\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">LR_8</text>\n",
       "</g>\n",
       "<!-- LR_6 -->\n",
       "<g id=\"node7\" class=\"node\">\n",
       "<title>LR_6</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"323.24\" cy=\"-172.85\" rx=\"31.7\" ry=\"31.7\"/>\n",
       "<text text-anchor=\"middle\" x=\"323.24\" y=\"-169.15\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">LR_6</text>\n",
       "</g>\n",
       "<!-- LR_8&#45;&gt;LR_6 -->\n",
       "<g id=\"edge13\" class=\"edge\">\n",
       "<title>LR_8&#45;&gt;LR_6</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M668.7,-158.83C625.38,-165.98 548.87,-177.52 482.78,-181.85 454.53,-183.7 447.36,-183.19 419.08,-181.85 401.3,-181.01 381.7,-179.28 364.95,-177.56\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"365.25,-174.07 354.94,-176.5 364.51,-181.04 365.25,-174.07\"/>\n",
       "<text text-anchor=\"middle\" x=\"513.28\" y=\"-183.65\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">S(b)</text>\n",
       "</g>\n",
       "<!-- LR_5 -->\n",
       "<g id=\"node8\" class=\"node\">\n",
       "<title>LR_5</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"450.93\" cy=\"-107.85\" rx=\"31.7\" ry=\"31.7\"/>\n",
       "<text text-anchor=\"middle\" x=\"450.93\" y=\"-104.15\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">LR_5</text>\n",
       "</g>\n",
       "<!-- LR_8&#45;&gt;LR_5 -->\n",
       "<g id=\"edge14\" class=\"edge\">\n",
       "<title>LR_8&#45;&gt;LR_5</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M668.83,-147.36C628.46,-140.82 559.62,-129.34 500.78,-117.85 497.99,-117.3 495.11,-116.73 492.22,-116.15\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"492.89,-112.72 482.4,-114.17 491.51,-119.58 492.89,-112.72\"/>\n",
       "<text text-anchor=\"middle\" x=\"575.62\" y=\"-139.65\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">S(a)</text>\n",
       "</g>\n",
       "<!-- LR_2&#45;&gt;LR_4 -->\n",
       "<g id=\"edge6\" class=\"edge\">\n",
       "<title>LR_2&#45;&gt;LR_4</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M198.14,-173.42C222.46,-196.62 261.37,-233.76 289.13,-260.26\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"287,-263.06 296.65,-267.43 291.83,-257.99 287,-263.06\"/>\n",
       "<text text-anchor=\"middle\" x=\"246.89\" y=\"-241.65\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">S(A)</text>\n",
       "</g>\n",
       "<!-- LR_2&#45;&gt;LR_6 -->\n",
       "<g id=\"edge4\" class=\"edge\">\n",
       "<title>LR_2&#45;&gt;LR_6</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M206.29,-156.25C228.1,-159.37 257.6,-163.59 281.38,-167\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"281.13,-170.5 291.52,-168.45 282.12,-163.57 281.13,-170.5\"/>\n",
       "<text text-anchor=\"middle\" x=\"246.89\" y=\"-167.65\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">SS(b)</text>\n",
       "</g>\n",
       "<!-- LR_2&#45;&gt;LR_5 -->\n",
       "<g id=\"edge5\" class=\"edge\">\n",
       "<title>LR_2&#45;&gt;LR_5</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M204.48,-140.61C226.77,-132.49 258.56,-122.07 287.39,-116.85 328.17,-109.46 375.56,-107.58 408.61,-107.32\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"408.82,-110.82 418.81,-107.29 408.8,-103.82 408.82,-110.82\"/>\n",
       "<text text-anchor=\"middle\" x=\"323.24\" y=\"-120.65\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">SS(a)</text>\n",
       "</g>\n",
       "<!-- LR_1&#45;&gt;LR_3 -->\n",
       "<g id=\"edge3\" class=\"edge\">\n",
       "<title>LR_1&#45;&gt;LR_3</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M206.65,-41.36C227.15,-40.38 254.31,-39.09 277.16,-38\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"277.49,-41.49 287.31,-37.51 277.16,-34.49 277.49,-41.49\"/>\n",
       "<text text-anchor=\"middle\" x=\"246.89\" y=\"-44.65\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">S($end)</text>\n",
       "</g>\n",
       "<!-- LR_6&#45;&gt;LR_6 -->\n",
       "<g id=\"edge9\" class=\"edge\">\n",
       "<title>LR_6&#45;&gt;LR_6</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M311.26,-202.53C310.87,-213.59 314.86,-222.69 323.24,-222.69 328.86,-222.69 332.51,-218.58 334.18,-212.53\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"337.67,-212.83 335.21,-202.53 330.7,-212.12 337.67,-212.83\"/>\n",
       "<text text-anchor=\"middle\" x=\"323.24\" y=\"-226.49\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">S(b)</text>\n",
       "</g>\n",
       "<!-- LR_6&#45;&gt;LR_5 -->\n",
       "<g id=\"edge10\" class=\"edge\">\n",
       "<title>LR_6&#45;&gt;LR_5</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M351.82,-158.58C369.91,-149.23 393.77,-136.89 413.43,-126.72\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"415.14,-129.78 422.41,-122.08 411.92,-123.56 415.14,-129.78\"/>\n",
       "<text text-anchor=\"middle\" x=\"389.08\" y=\"-147.65\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">S(a)</text>\n",
       "</g>\n",
       "<!-- LR_5&#45;&gt;LR_5 -->\n",
       "<g id=\"edge8\" class=\"edge\">\n",
       "<title>LR_5&#45;&gt;LR_5</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M439.69,-138.02C439.45,-148.86 443.2,-157.69 450.93,-157.69 456.01,-157.69 459.36,-153.89 461,-148.21\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"464.51,-148.35 462.17,-138.02 457.56,-147.56 464.51,-148.35\"/>\n",
       "<text text-anchor=\"middle\" x=\"450.93\" y=\"-161.49\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">S(a)</text>\n",
       "</g>\n",
       "<!-- LR_7 -->\n",
       "<g id=\"node9\" class=\"node\">\n",
       "<title>LR_7</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"575.62\" cy=\"-84.85\" rx=\"31.7\" ry=\"31.7\"/>\n",
       "<text text-anchor=\"middle\" x=\"575.62\" y=\"-81.15\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">LR_7</text>\n",
       "</g>\n",
       "<!-- LR_5&#45;&gt;LR_7 -->\n",
       "<g id=\"edge7\" class=\"edge\">\n",
       "<title>LR_5&#45;&gt;LR_7</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M482.57,-102.1C498.09,-99.19 517.14,-95.62 533.88,-92.49\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"534.76,-95.88 543.95,-90.6 533.47,-89 534.76,-95.88\"/>\n",
       "<text text-anchor=\"middle\" x=\"513.28\" y=\"-102.65\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">S(b)</text>\n",
       "</g>\n",
       "<!-- LR_7&#45;&gt;LR_8 -->\n",
       "<g id=\"edge11\" class=\"edge\">\n",
       "<title>LR_7&#45;&gt;LR_8</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M604.38,-99.37C618.26,-106.67 635.28,-115.67 650.47,-123.85 654.74,-126.14 659.19,-128.56 663.62,-130.98\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"662.17,-134.17 672.62,-135.9 665.53,-128.03 662.17,-134.17\"/>\n",
       "<text text-anchor=\"middle\" x=\"637.97\" y=\"-127.65\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">S(b)</text>\n",
       "</g>\n",
       "<!-- LR_7&#45;&gt;LR_5 -->\n",
       "<g id=\"edge12\" class=\"edge\">\n",
       "<title>LR_7&#45;&gt;LR_5</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M545.05,-75.8C531.36,-72.99 515.01,-71.6 500.78,-75.85 495.43,-77.44 490.13,-79.83 485.1,-82.59\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"483.11,-79.7 476.38,-87.89 486.75,-85.69 483.11,-79.7\"/>\n",
       "<text text-anchor=\"middle\" x=\"513.28\" y=\"-79.65\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">S(a)</text>\n",
       "</g>\n",
       "</g>\n",
       "</svg>\n"
      ],
      "text/plain": [
       "<graphviz.graphs.Digraph at 0x203f27271f0>"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# http://www.graphviz.org/content/fsm\n",
    "\n",
    "f = graphviz.Digraph('finite_state_machine', filename='fsm.gv')\n",
    "\n",
    "f.attr(rankdir='LR', size='8,5')\n",
    "\n",
    "f.attr('node', shape='doublecircle')\n",
    "f.node('LR_0')\n",
    "f.node('LR_3')\n",
    "f.node('LR_4')\n",
    "f.node('LR_8')\n",
    "\n",
    "f.attr('node', shape='circle')\n",
    "f.edge('LR_0', 'LR_2', label='SS(B)')\n",
    "f.edge('LR_0', 'LR_1', label='SS(S)')\n",
    "f.edge('LR_1', 'LR_3', label='S($end)')\n",
    "f.edge('LR_2', 'LR_6', label='SS(b)')\n",
    "f.edge('LR_2', 'LR_5', label='SS(a)')\n",
    "f.edge('LR_2', 'LR_4', label='S(A)')\n",
    "f.edge('LR_5', 'LR_7', label='S(b)')\n",
    "f.edge('LR_5', 'LR_5', label='S(a)')\n",
    "f.edge('LR_6', 'LR_6', label='S(b)')\n",
    "f.edge('LR_6', 'LR_5', label='S(a)')\n",
    "f.edge('LR_7', 'LR_8', label='S(b)')\n",
    "f.edge('LR_7', 'LR_5', label='S(a)')\n",
    "f.edge('LR_8', 'LR_6', label='S(b)')\n",
    "f.edge('LR_8', 'LR_5', label='S(a)')\n",
    "\n",
    "f"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[DEBUG@graphviz.backend.execute] run [WindowsPath('dot'), '-Kdot', '-Tsvg']\n"
     ]
    },
    {
     "data": {
      "image/svg+xml": [
       "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
       "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
       " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
       "<!-- Generated by graphviz version 2.49.3 (20211023.0002)\n",
       " -->\n",
       "<!-- Title: G Pages: 1 -->\n",
       "<svg width=\"222pt\" height=\"364pt\"\n",
       " viewBox=\"0.00 0.00 222.00 364.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
       "<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 360)\">\n",
       "<title>G</title>\n",
       "<polygon fill=\"white\" stroke=\"transparent\" points=\"-4,4 -4,-360 218,-360 218,4 -4,4\"/>\n",
       "<g id=\"clust1\" class=\"cluster\">\n",
       "<title>cluster0</title>\n",
       "<polygon fill=\"none\" stroke=\"black\" points=\"64,-152 64,-348 206,-348 206,-152 64,-152\"/>\n",
       "</g>\n",
       "<g id=\"clust2\" class=\"cluster\">\n",
       "<title>cluster1</title>\n",
       "<polygon fill=\"none\" stroke=\"black\" points=\"64,-8 64,-132 206,-132 206,-8 64,-8\"/>\n",
       "</g>\n",
       "<!-- a -->\n",
       "<g id=\"node1\" class=\"node\">\n",
       "<title>a</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"135\" cy=\"-322\" rx=\"27\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"135\" y=\"-318.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">a</text>\n",
       "</g>\n",
       "<!-- b -->\n",
       "<g id=\"node2\" class=\"node\">\n",
       "<title>b</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"99\" cy=\"-250\" rx=\"27\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"99\" y=\"-246.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">b</text>\n",
       "</g>\n",
       "<!-- a&#45;&gt;b -->\n",
       "<g id=\"edge1\" class=\"edge\">\n",
       "<title>a&#45;&gt;b</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M126.65,-304.76C122.29,-296.28 116.85,-285.71 111.96,-276.2\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"114.99,-274.44 107.3,-267.15 108.77,-277.64 114.99,-274.44\"/>\n",
       "</g>\n",
       "<!-- c -->\n",
       "<g id=\"node3\" class=\"node\">\n",
       "<title>c</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"171\" cy=\"-250\" rx=\"27\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"171\" y=\"-246.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">c</text>\n",
       "</g>\n",
       "<!-- a&#45;&gt;c -->\n",
       "<g id=\"edge2\" class=\"edge\">\n",
       "<title>a&#45;&gt;c</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M143.35,-304.76C147.71,-296.28 153.15,-285.71 158.04,-276.2\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"161.23,-277.64 162.7,-267.15 155.01,-274.44 161.23,-277.64\"/>\n",
       "</g>\n",
       "<!-- d -->\n",
       "<g id=\"node4\" class=\"node\">\n",
       "<title>d</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"99\" cy=\"-178\" rx=\"27\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"99\" y=\"-174.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">d</text>\n",
       "</g>\n",
       "<!-- b&#45;&gt;d -->\n",
       "<g id=\"edge3\" class=\"edge\">\n",
       "<title>b&#45;&gt;d</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M99,-231.7C99,-223.98 99,-214.71 99,-206.11\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"102.5,-206.1 99,-196.1 95.5,-206.1 102.5,-206.1\"/>\n",
       "</g>\n",
       "<!-- f -->\n",
       "<g id=\"node7\" class=\"node\">\n",
       "<title>f</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"99\" cy=\"-34\" rx=\"27\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"99\" y=\"-30.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">f</text>\n",
       "</g>\n",
       "<!-- b&#45;&gt;f -->\n",
       "<g id=\"edge7\" class=\"edge\">\n",
       "<title>b&#45;&gt;f</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M112.75,-234.07C120.96,-224.1 130.62,-210.25 135,-196 142.02,-173.17 145.55,-157.68 145.58,-142.23\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"149.07,-141.82 145.1,-132 142.07,-142.15 149.07,-141.82\"/>\n",
       "</g>\n",
       "<!-- c&#45;&gt;d -->\n",
       "<g id=\"edge4\" class=\"edge\">\n",
       "<title>c&#45;&gt;d</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M156.43,-234.83C146.25,-224.94 132.48,-211.55 120.97,-200.36\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"123.41,-197.85 113.8,-193.38 118.53,-202.87 123.41,-197.85\"/>\n",
       "</g>\n",
       "<!-- e -->\n",
       "<g id=\"node5\" class=\"node\">\n",
       "<title>e</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"99\" cy=\"-106\" rx=\"27\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"99\" y=\"-102.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">e</text>\n",
       "</g>\n",
       "<!-- c&#45;&gt;e -->\n",
       "<g id=\"edge10\" class=\"edge\">\n",
       "<title>c&#45;&gt;e</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M135,-152C130.7,-144.41 125.16,-136.77 119.71,-129.99\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"122.07,-127.36 112.97,-121.94 116.71,-131.86 122.07,-127.36\"/>\n",
       "</g>\n",
       "<!-- g -->\n",
       "<g id=\"node6\" class=\"node\">\n",
       "<title>g</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"171\" cy=\"-34\" rx=\"27\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"171\" y=\"-30.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">g</text>\n",
       "</g>\n",
       "<!-- c&#45;&gt;g -->\n",
       "<g id=\"edge9\" class=\"edge\">\n",
       "<title>c&#45;&gt;g</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M171,-152C171,-148.77 171,-145.53 171,-142.29\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"174.5,-141.99 171,-132 167.5,-142 174.5,-141.99\"/>\n",
       "</g>\n",
       "<!-- d&#45;&gt;e -->\n",
       "<g id=\"edge8\" class=\"edge\">\n",
       "<title>d&#45;&gt;e</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M99,-159.7C99,-151.98 99,-142.71 99,-134.11\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"102.5,-134.1 99,-124.1 95.5,-134.1 102.5,-134.1\"/>\n",
       "</g>\n",
       "<!-- h -->\n",
       "<g id=\"node8\" class=\"node\">\n",
       "<title>h</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"27\" cy=\"-106\" rx=\"27\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"27\" y=\"-102.3\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">h</text>\n",
       "</g>\n",
       "<!-- d&#45;&gt;h -->\n",
       "<g id=\"edge11\" class=\"edge\">\n",
       "<title>d&#45;&gt;h</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M84.43,-162.83C74.25,-152.94 60.48,-139.55 48.97,-128.36\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"51.41,-125.85 41.8,-121.38 46.53,-130.87 51.41,-125.85\"/>\n",
       "</g>\n",
       "<!-- e&#45;&gt;g -->\n",
       "<g id=\"edge5\" class=\"edge\">\n",
       "<title>e&#45;&gt;g</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M113.57,-90.83C123.75,-80.94 137.52,-67.55 149.03,-56.36\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"151.47,-58.87 156.2,-49.38 146.59,-53.85 151.47,-58.87\"/>\n",
       "</g>\n",
       "<!-- e&#45;&gt;f -->\n",
       "<g id=\"edge6\" class=\"edge\">\n",
       "<title>e&#45;&gt;f</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M99,-87.7C99,-79.98 99,-70.71 99,-62.11\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"102.5,-62.1 99,-52.1 95.5,-62.1 102.5,-62.1\"/>\n",
       "</g>\n",
       "</g>\n",
       "</svg>\n"
      ],
      "text/plain": [
       "<graphviz.graphs.Digraph at 0x203f2726cb0>"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# http://www.graphviz.org/pdf/dotguide.pdf, Figure 20\n",
    "\n",
    "g = graphviz.Digraph('G', filename='cluster_edge.gv')\n",
    "\n",
    "g.attr(compound='true')\n",
    "\n",
    "with g.subgraph(name='cluster0') as c:\n",
    "    c.edges(['ab', 'ac', 'bd', 'cd'])\n",
    "\n",
    "with g.subgraph(name='cluster1') as c:\n",
    "    c.edges(['eg', 'ef'])\n",
    "\n",
    "g.edge('b', 'f', lhead='cluster1')\n",
    "g.edge('d', 'e')\n",
    "g.edge('c', 'g', ltail='cluster0', lhead='cluster1')\n",
    "g.edge('c', 'e', ltail='cluster0')\n",
    "g.edge('d', 'h')\n",
    "\n",
    "g"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
